﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using DDD;

namespace DevApp {
    public class Program3 :GameWindow {

        World wld;
        Graphics3D g3d;

        public Program3 ()
            : base (640, 480,
              new GraphicsMode (), "DDD: Trance Parency", 0,
              DisplayDevice.Default, 3, 0,
              GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug) {
        }

        protected override void OnLoad (System.EventArgs e) {
            var vert = new VertexShader ("Shaders/simple.vert");
            var frag = new FragmentShader ("Shaders/simple.frag");
            var shader = new ShaderProgram (vert, frag);

            var unifs = new UniformArray ();
            unifs.Add ("ModelViewMatrix", UniformArray.CurrentNode, () => ((Node)null).LocalToCamera);
            unifs.Add ("ProjectionMatrix", UniformArray.CurrentActiveCamera, () => ((Camera)null).ProjectionMatrix);
            unifs.Add ("Diffuse", UniformArray.CurrentMaterial, ()=>((PhongMaterial)null).Diffuse);

            var mat1 = new PhongMaterial ();
            mat1.SetDiffuse(1.0f,0.0f,0.0f,0.0f);

            var cmp1 = new CompositeMode ();
            cmp1.SetColorBlendFunction (ColorBlendFunction.Add);

            var app1 = new Appearance ();
            app1.SetShaderProgram (shader);
            app1.AddUniformArray (unifs);
            app1.SetMaterial (mat1);
            app1.SetComositeMode (cmp1);

            var msh1 = MeshBuilder.CreateSquare (3, 4, 4, "v_Position", null, null);
            msh1.SetAppearance (app1);

            var node1 = new Node ();
            node1.Attach (msh1);
            node1.UserID = 101;
            node1.Translate (-1, 0, -0.1f);

            var mat2 = new PhongMaterial ();
            mat2.SetDiffuse (0.0f, 0.0f, 1.0f, 0.0f);
            Console.WriteLine ("D = " + mat2.Diffuse);

            var cmp2 = new CompositeMode ();
            cmp2.SetColorBlendFunction (ColorBlendFunction.Add);

            var app2 = new Appearance ();
            app2.SetShaderProgram (shader);
            app2.AddUniformArray (unifs);
            app2.SetMaterial (mat2);
            app2.SetComositeMode (cmp2);

            var msh2 = MeshBuilder.CreateSquare (2, 4, 4, "v_Position", null, null);
            msh2.SetAppearance (app2);

            
            var node2 = new Node ();
            node2.Attach (msh2);
            node2.UserID = 102;
            node2.Translate (1, 0, 0.1f);

            var cam = new Camera ();
            cam.SetPerspective (45, Width / (float)Height, 0.1f, 100f);

            var node3 = new Node ();
            node3.Attach (cam);
            node3.SetTranslation (0, 0, 10);

            wld = new World ();
            wld.AddChild (node1);
            wld.AddChild (node2);
            wld.AddChild (node3);
            wld.SetActiveCamera (node3);

            g3d = Graphics3D.GetInstance ();
            g3d.RenderPass += delegate {
                g3d.SetWorld (wld);
                g3d.SetClearColor (0, 0, 1, 1);
                g3d.SetClearDepth (1);
                g3d.SetColorClearEnabled (true);
                g3d.SetDepthClearEnabled (true);
                g3d.SetViewort (0, 0, Width, Height);
            };


            // 未実装
            VSync = VSyncMode.On;
        }

        protected override void OnUnload (EventArgs e) {
            wld = null;
            GC.Collect ();
            g3d.Release ();
        }

        protected override void OnUpdateFrame (FrameEventArgs e) {
           
        }

        protected override void OnRenderFrame (FrameEventArgs e) {

            g3d.Render ();

            SwapBuffers ();
        }

        /*
        [STAThread]
        public static void Main () {
            using (var example = new Program3 ()) {
                example.Run (30);
            }
        }
         * */
        
    }
}
